/**   
 * Model Created on 2022年4月28日
 *   
 * Copyright (c) 2018 by Kunrong.HOo.
 */ 
package com.seaside.park.api;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import com.seaside.park.service.NotifyService;
import com.seaside.parkCommon.bean.AccessRecord;
import com.seaside.parkCommon.mapper.AccessRecordMapper;
import com.seaside.parkCommon.vo.yz.BerthInOutVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.seaside.common.bean.Result;
import com.seaside.park.service.ParkService;
import com.seaside.park.service.ParkingService;
import com.seaside.park.vo.notify.CarInOutVO;
import com.seaside.park.vo.notify.OrderVO;
import com.seaside.park.vo.notify.QueryBerthParkingVO;
import com.seaside.park.vo.notify.QueryBerthResultVO;
import com.seaside.parkCommon.bean.ParkPlace;
import com.seaside.parkCommon.bean.ReserveOrder;
import com.seaside.parkCommon.mapper.ReserveOrderMapper;
import com.seaside.parkCommon.util.SignUtil;
import com.seaside.parkCommon.vo.yz.RequestParam;
import com.seaside.parkCommon.vo.yz.RespData;
import com.seaside.parkCommon.vo.yz.RespResult;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @author <a href="mailto:hoocoral@hotmail.com">Kunrong.HOo</a>
 * @version 1.0
 */
@Slf4j
@Api(tags="订单接口")
@RestController
@RequestMapping("/api/notify")
public class NotifyAPI {
	
	@Autowired
	private ParkingService parkingService;

	@Autowired
	private ParkService parkService;
	
	@Autowired
	private ReserveOrderMapper orderMapper;
	
	@Autowired
	private AccessRecordMapper accessRecordMapper;

	@ApiOperation(value = "车位预约成功通知接口", response = RespResult.class)
    @ApiImplicitParams({
    	@ApiImplicitParam(name = "params", dataTypeClass = RequestParam.class, required = true, value = "预约订单"),
    }) 
    @PostMapping("/order")
    public RespResult<RespData> orderNotify(@RequestBody RequestParam<OrderVO> params) {
		
		if (params == null) {
			return RespResult.error("101", "参数错误！");
		}
		
		if (!SignUtil.verify(params.getReqData(), params.getSign())) {
			return RespResult.error("102", "签名错误！");
		}
		
		OrderVO vo = params.getReqData();
		log.info("###[预约]：" + JSON.toJSONString(vo));
		
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
			
			ReserveOrder order = new ReserveOrder();
			order.setOrderTime(new Date());
			order.setOrderInTime(sdf.parse(vo.getOrderTime()));
			order.setOrderOutTime(sdf.parse(vo.getOrderOutTime()));
			order.setCarPlate(vo.getCarPlate());
			order.setBerthNumber(vo.getBerthNumber());
			order.setParkZoneId(vo.getParkZoneId());
			order.setPhoneNumber(vo.getPhoneNumber());

			Result<ParkPlace> parkPlaceRet = parkingService.reservationBerth(vo);
			if (parkPlaceRet.isSucess()) {
				ParkPlace parkPlace = parkPlaceRet.getData();
				if (parkPlace != null) {
					order.setParkPlaceId(parkPlace.getParkId());
				}
			}
			
			orderMapper.insert(order);
			
			
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			return RespResult.error("103", "服务器错误！");
		}
        
        return RespResult.success();
    }

	@ApiOperation(value = "车辆进/出场通知接口", response = RespResult.class)
    @ApiImplicitParams({
    	@ApiImplicitParam(name = "params", dataTypeClass = RequestParam.class, required = true, value = "车辆进/出场通知对象"),
    }) 
    @PostMapping("/inout")
    public RespResult<RespData> inoutNotify(@RequestBody RequestParam<CarInOutVO> params) {
		
		if (params == null) {
			return RespResult.error("101", "参数错误！");
		}

		// 取消验签
//		if (!SignUtil.verify(params.getReqData(), params.getSign())) {
//			return RespResult.error("102", "签名错误！");
//		}
		
		CarInOutVO vo = params.getReqData();
		log.info("###[出入场]：" + JSON.toJSONString(vo));
		
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
			
			// 操作记录
			AccessRecord accessRecord = new AccessRecord();
			accessRecord.setBerthNumber(vo.getBerthNumber());
			accessRecord.setCarPlate(vo.getCarPlate());
			accessRecord.setEventTime(sdf.parse(vo.getEventTime()));
			accessRecord.setEventType(vo.getEventType());
			accessRecord.setParkZoneId(vo.getParkZoneId());
			// 新增临停车辆类型字段
			accessRecord.setCarPlateType(vo.getCarPlateType());
			
			accessRecordMapper.insert(accessRecord);
			
			if("IN".equals(vo.getEventType())) {
				parkingService.enterParkZone(vo);
			} else if ("OUT".equals(vo.getEventType())) {
				parkingService.leaveParkZone(vo);
			} else {
				log.error("错误的事件类型：【" + vo.getEventType() + "】");
			}
			
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			return RespResult.error("103", "服务器错误！");
		}
		
        return RespResult.success();
    }
	
	
	@ApiOperation(value = "泊位查询对象接口", response = RespResult.class)
    @ApiImplicitParams({
    	@ApiImplicitParam(name = "params", dataTypeClass = RequestParam.class, required = true, value = "泊位查询对象"),
    }) 
    @PostMapping("/queryBerthParkingInfo")
    public RespResult<RespData> queryBerthParkingInfo(@RequestBody RequestParam<QueryBerthParkingVO> params) {
		
		if (params == null) {
			return RespResult.error("101", "参数错误！");
		}
		
		if (!SignUtil.verify(params.getReqData(), params.getSign())) {
			return RespResult.error("102", "签名错误！");
		}
		
		QueryBerthParkingVO vo = params.getReqData();
		log.info("###[泊位查询]：" + JSON.toJSONString(vo));
		
		try {
			
			Result<List<ParkPlace>> parkPlaceListRet = parkService.getParkPlaceStatus(vo.getParkZoneId(), vo.getBerthNumbers());
			if (!parkPlaceListRet.isSucess()) {
				return RespResult.error(parkPlaceListRet.getMsg());
			}
			
			List<ParkPlace> parkPlaceList = parkPlaceListRet.getData();
			List<QueryBerthResultVO> queryResultList = parkPlaceList.stream().map(park -> {
				QueryBerthResultVO result = new QueryBerthResultVO();
				result.setBerthNumber(park.getParkNo());
				result.setCarPlate(park.getCurrPlate());
				return result;
			}).collect(Collectors.toList());
			
			RespData data = new RespData(true, queryResultList);
			
			return RespResult.success(data);
			
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			return RespResult.error("103", "服务器错误！");
		}
    }
}